package com.gt.platform.service.impl;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gt.common.DateUtils;
import com.gt.common.GenerateUtil;
import com.gt.common.JsonToXmlConverter;
import com.gt.common.WebServiceUtil;
import com.gt.common.XmlParse;
import com.gt.platform.domain.ApplyReqInfo;
import com.gt.platform.domain.ApplyReqInfoDetail;
import com.gt.platform.domain.ApplyReqInfoVo;
import com.gt.platform.domain.Head;
import com.gt.platform.domain.InPut;
import com.gt.platform.domain.InPutDetail;
import com.gt.platform.domain.ReqParam;
import com.gt.platform.domain.ReqParamDetail;
import com.gt.platform.mapper.PlatformMapper;
import com.gt.platform.service.PlatformService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

@Slf4j
@Service
public class PlatformServiceImpl implements PlatformService {

    @Autowired
    private PlatformMapper platformMapper;

    @Autowired
    private Executor executorTask;


    /**
     * 查询检查申请列表 S5001
     * 查询检查申请详情 S5002
     *
     * @param applyReqInfoVo
     * @return
     */
    @Override
    public String selectCheckApplyList(ApplyReqInfoVo applyReqInfoVo) {

        /**封装请求参数**/
        ApplyReqInfo applyReqInfo = createInParam(applyReqInfoVo);
        ReqParam reqParam = new ReqParam();
        InPut inPut = new InPut();
        Head head = new Head();
        head.setTime(DateUtils.getDateTime());
        head.setAction_no(GenerateUtil.publicSerialNumber());
        head.setTarno("ZLHIS");
        head.setSysno("GTCSXT");
        head.setBizno("S5001");
        inPut.setHead(head);
        reqParam.setInput(inPut);
        inPut.setReq_info(applyReqInfo);
        String data = JSON.toJSONString(reqParam);

        try {
            String checkResult = WebServiceUtil.sendData("", "ESB_PlatformSwitch");/**任何接口调用前都要调用此开关接口**/
            String checkData = XmlParse.parse(checkResult, "Data");
            if (!"true".equals(checkData)) {
                log.error("平台服务不可用{}", applyReqInfo.getQuery_content());
                return "平台服务不可用";
            }
            String returnResult = WebServiceUtil.sendData(data, "HIS_S5001");
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode rootNode = objectMapper.readTree(returnResult);
            JsonNode input = rootNode.get("input");
            JsonNode ackInfo = input.get("ack_info");
            String exeStatus = ackInfo.get("exe_status").toString();

            exeStatus = exeStatus.replaceAll("^\"|\"$", "");
            if (exeStatus.equals("E")) {
                log.error("调用平台执行错误,错误消息{}", ackInfo.get("err_msg"));
                String errMsg = ackInfo.get("err_msg").toString();
                errMsg = errMsg.replaceFirst("^\"", "").replaceFirst("\"$", "");
                return errMsg;
            }
            JsonNode applyInfo = input.get("apply_info");
            createCheckApplyDetail(applyInfo, applyReqInfoVo.getSearchid());
            return "true";
        } catch (Exception e) {
            log.error("查询申请单异常【{}】", applyReqInfo.getQuery_content());
            e.printStackTrace();
            return "服务器内部异常";
        }

    }

    /**
     * 构造前端入参
     *
     * @param applyReqInfoVo
     * @return
     */
    private ApplyReqInfo createInParam(ApplyReqInfoVo applyReqInfoVo) {
        ApplyReqInfo applyReqInfo = new ApplyReqInfo();
        String patSource = applyReqInfoVo.getPatsource();
        switch (patSource) {
            case "病人id":
                applyReqInfo.setQuery_key("1");
                break;
            case "身份证号":
                applyReqInfo.setQuery_key("3");
                break;
            case "门诊号":
                applyReqInfo.setQuery_key("5");
                break;
            case "挂号单号":
                applyReqInfo.setQuery_key("6");
                break;
            case "住院号":
                applyReqInfo.setQuery_key("7");
                break;
            case "医嘱id":
                applyReqInfo.setQuery_key("8");
                break;
            case "申请单号":
                applyReqInfo.setQuery_key("8");
                break;
            default:
                applyReqInfo.setQuery_key("9");
        }


        applyReqInfo.setQuery_content(applyReqInfoVo.getHisid());
        applyReqInfo.setStart_date(applyReqInfoVo.getStartdate() + " 00:00:00");
        String endDate = dateAddOne(applyReqInfoVo.getEnddate());
        applyReqInfo.setEnd_date(endDate);
        applyReqInfo.setPvid("");
        applyReqInfo.setOperation_type("");
        applyReqInfo.setVisit_type("");
        return applyReqInfo;
    }

    /**
     * 截止时间加一
     *
     * @param endDate
     * @return
     */
    public String dateAddOne(String endDate) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 将字符串转换为LocalDate
        LocalDate date = LocalDate.parse(endDate, formatter);

        // 增加一天
        LocalDate newDate = date.plusDays(1);

        // 将LocalDate转换回字符串
        String newDateStr = newDate.format(formatter);

        newDateStr = newDateStr + " 00:00:00";

        return newDateStr;
    }

    private void createCheckApplyDetail(JsonNode applyInfo, String searchId) throws Exception {
        long start = System.currentTimeMillis();
        List<CompletableFuture> completableFutures = new ArrayList<>();
        for (JsonNode jsonNode : applyInfo) {
            CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
                String applyId = jsonNode.get("apply_id").toString();
                applyId = applyId.replaceFirst("^\"", "").replaceFirst("\"$", "");
                try {
                    selectApplyDetail(applyId, searchId);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("异步调用申请单异常，申请单号【{}】",applyId);
                }
            }, executorTask);
            completableFutures.add(completableFuture);
        }

        CompletableFuture[] completableFuturesArray = completableFutures.toArray(new CompletableFuture[0]);
        CompletableFuture.allOf(completableFuturesArray).join();

        long time =  System.currentTimeMillis() - start;
        log.info("调用平台明细消耗时间【{}】",time);
    }

    /**
     * 调用平台，查询明细数据
     *
     * @param applyId
     * @throws JsonProcessingException
     */
    private void selectApplyDetail(String applyId, String searchId) throws Exception {

        /**封装请求参数**/
        ReqParamDetail reqParamDetail = new ReqParamDetail();
        InPutDetail inPutDetail = new InPutDetail();
        ApplyReqInfoDetail applyReqInfoDetail = new ApplyReqInfoDetail();
        Head head = new Head();
        head.setTime(DateUtils.getDateTime());
        head.setAction_no(GenerateUtil.publicSerialNumber());
        head.setTarno("ZLHIS");
        head.setSysno("GTCSXT");
        head.setBizno("S5002");
        applyReqInfoDetail.setApply_id(applyId);
        inPutDetail.setReq_info(applyReqInfoDetail);
        inPutDetail.setHead(head);
        reqParamDetail.setInput(inPutDetail);
        String data = JSON.toJSONString(reqParamDetail);

        String returnResult = WebServiceUtil.sendData(data, "HIS_S5002");
        long start = System.currentTimeMillis();
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(returnResult);
        JsonNode input = rootNode.get("input");
        JsonNode ackInfo = input.get("ack_info");
        String exeStatus = ackInfo.get("exe_status").toString();
        exeStatus = exeStatus.replaceAll("^\"|\"$", "");
        if (exeStatus.equals("E")) {
            log.error("调用平台执行错误,通过申请单id查询详细信息【{}】，错误消息{}", applyId, ackInfo.get("err_msg"));
        }

        String xmlData = JsonToXmlConverter.convertToXml(returnResult);
        xmlData = xmlData.replace("<ObjectNode>", "<Root>").replace("</ObjectNode>", "</Root>");
        long time =  System.currentTimeMillis() - start;
        log.info("格式化数据时间【{}】",time);
        long start1 = System.currentTimeMillis();
        platformMapper.saveApplyDetail(xmlData, searchId);
        long time1 =  System.currentTimeMillis() - start1;
        log.info("入库时间【{}】",time1);

    }

    @Override
    public String selectCheckApplyDetail(String data) {
        //todo 7.64查询检查申请列表 S5001
        //todo 7.65查询检查申请详情 S5002
        String returnData = null;
        try {
            String checkResult = WebServiceUtil.sendData(data, "secure");
            String checkData = XmlParse.parse(checkResult, "Data");
            if (!"true".equals(checkData)) {
                log.error("平台服务不可用");
                return "false";
            }
            String returnResult = WebServiceUtil.sendData(data, "secure");
            returnData = XmlParse.parse(returnResult, "Data");
            System.out.println(returnData);
            //todo 如果成功删除数据，不成功不删除
        } catch (Exception e) {
            log.error("查询申请单异常");
            e.printStackTrace();
        }
        return returnData;
    }

}
